#include "carcount.h"
#include "ui_carcount.h"

#include <QMouseEvent>
#include <QPainter>
#include <QDebug>
#include <math.h>

#define height_h 30
#define width_w 30


CarCount::CarCount(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::CarCount)
{
    ui->setupUi(this);
    //运动对象背景分离对象

    bgMOG2 = cv::createBackgroundSubtractorMOG2();
    bgMOG2->setVarThreshold(50);  //方差阈值，主要用于判断前景还是背景

    //初始化ui数组
    ui->label->installEventFilter( this );
    x=y=x2=y2=x_1=y_1=x_2=y_2=x_3=y_3=0;
    startTimer(50);
    //打开摄像头设备(笔记本自带为0,USB外接为7)
    this->cap.open(7);
    //监测区域绘制
    x_1 =50;
    y_1 = 100;
    ui->x1Lb->setText(QString::number(x_1));
    ui->y1Lb->setText(QString::number(y_1));


    ui->x2Lb->setText(QString::number(x_1+width_w));
    ui->y2Lb->setText(QString::number(y_1+height_h));



    x_2 = 100;
    y_2 = 100;
    ui->x1Lb_2->setText(QString::number(x_2));
    ui->y1Lb_2->setText(QString::number(y_2));


    ui->x2Lb_2->setText(QString::number(x_2+width_w));
    ui->y2Lb_2->setText(QString::number(y_2+height_h));

    x_3 = 150;
    y_3 = 100;
    ui->x1Lb_3->setText(QString::number(x_3));
    ui->y1Lb_3->setText(QString::number(y_3));


    ui->x2Lb_3->setText(QString::number(x_3+width_w));
    ui->y2Lb_3->setText(QString::number(y_3+height_h));


}

CarCount::~CarCount()
{
    delete ui;
}

//鼠标按下
void CarCount::mousePressEvent(QMouseEvent *)
{

}

// 鼠标移动事件
void CarCount::mouseMoveEvent(QMouseEvent *)
{

}

void CarCount::paint()
{

}

bool CarCount::eventFilter(QObject *obj, QEvent *e)
{
    if(e->type() == QEvent::Paint)
    {
        paint();
    }
    return QMainWindow::eventFilter(obj,e);
}

void CarCount::timerEvent(QTimerEvent *)
{

    //采集一帧数据
    cv::Mat FrameImage;
    cap.read(FrameImage);
    //转大小
    cv::Mat newImage;
    //与界面显示一样
    //ARM开发板用↓
    cv::resize(FrameImage, newImage, cv::Size(320,240));
    //Windows用↓
    //        cv::resize(FrameImage, newImage, cv::Size(ui->label->rect().width(),ui->label->height()));
    //resize(输入原图像，即待改变大小的图像,输出改变后的图像, 输出图像的大小)缩小或者放大函数至某一个大小


    //    cv::Rect rect(x,y,abs(x2-x),abs(y2-y));//检测区域rect(矩形左上角起始坐标的x，矩形左上角起始坐标的y，宽，高)
    cv::Rect rect_1;
    cv::Rect rect_2;
    cv::Rect rect_3;

    rect_1.x = x_1;
    rect_1.y = y_1;
    rect_1.width = height_h;
    rect_1.height = width_w;
    cv::rectangle(newImage,rect_1,cv::Scalar(255,0,0));//画检测区域线(,设置颜色为红色)

    rect_2.x = x_2;
    rect_2.y = y_2;
    rect_2.width = height_h;
    rect_2.height = width_w;
    cv::rectangle(newImage,rect_2,cv::Scalar(255,0,0));//画检测区域线(,cv::Scalar设置颜色为红色)

    rect_3.x = x_3;
    rect_3.y = y_3;
    rect_3.width = height_h;
    rect_3.height = width_w;
    cv::rectangle(newImage,rect_3,cv::Scalar(255,0,0));//画检测区域线(,设置颜色为红色)

    QImage image=QImage(newImage.data,newImage.cols,newImage.rows,newImage.step,QImage::Format_RGB888);
    QPixmap pix;
    ui->label->setPixmap(pix.fromImage(image).scaled(ui->label->rect().width(),ui->label->rect().height()));
    update();

    //转灰度
    cv::Mat grayImage;
    cv::cvtColor(newImage, grayImage, cv::COLOR_RGB2GRAY);  //转换为灰度图
    cv::blur(grayImage, grayImage, cv::Size(3, 3));		//使用平滑运算

    //使用MOG2算法提取前景
    cv::Mat outImage;
    bgMOG2->apply(grayImage,outImage,-1);

    if(!outImage.empty())
    {
        cv::Mat showMat;
        outImage.copyTo(showMat);
        //*****************************************  1  ***********************************

        // 1
        cv::Mat subMat = outImage(rect_1);	//再MOG2的前景提取结果中，取车道标记矩形框区域为subMat矩阵
        cv::Mat sumMat;		//积分图 == subMat的积分矩阵
        cv::integral(subMat, sumMat, CV_32S);		//设置积分矩阵的数据类型为int；
        int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值，就是矩形框内亮度和；


        //循环打印判断
        qDebug()<<"*****NO.1******"<<sumValue;
        static int flag_time = 0;
        static double t1=0,t2=0;
        static int LanneLightSum_prev;			//车道亮度和：上一帧的
        if(sumValue > 30000)
        {
            if(flag_time== 0)
            {
                //开始计时
                t1 = (double)cv::getCPUTickCount();
                flag_time = 1;
            }
        }

        if (LanneLightSum_prev > 30000  && sumValue <= 30000)
        {
            if(flag_time== 1)
            {
                //结束计时
                t2 = (double)cv::getCPUTickCount();
                flag_time = 0;
            }

            //:: 车辆通过了矩形框：上一帧亮度和大于阈值，本帧亮度和小于阈值；车辆计数器自加；
            ++LanneCarCnt;
            LanneLightSum_prev= sumValue;
            // 时间计算
            ui->time1Lb->setText(QString("%1ms").arg((int)(1e3 *(t2-t1)/(double)cv::getTickFrequency())));
        }
        else
            LanneLightSum_prev = sumValue;  //存储当前亮度和到LanneLightSum_prev


        qDebug()<<"NO.1:"<<LanneCarCnt;
        ui->pass1Lb->setText(QString::number(LanneCarCnt));
        //速度计算
        int speed = (int)(3.0/((1e3 *(t2-t1)/(double)cv::getTickFrequency())*(1e-3)))*3.6;
        if(speed > 0)
            ui->label_9->setText(QString("%1km/h").arg(speed));


        //*****************************************  2  ***********************************

        // 2
        cv::Mat subMat_2 = outImage(rect_2);	//再MOG2的前景提取结果中，取车道标记矩形框区域为subMat矩阵
        cv::Mat sumMat_2;		//积分图 == subMat的积分矩阵
        cv::integral(subMat_2, sumMat_2, CV_32S);		//设置积分矩阵的数据类型为int；
        int sumValue_2 = (int)sumMat_2.at<int>((int)sumMat_2.rows - 1, (int)sumMat_2.cols - 1);
        //获取积分图右下角的值，就是矩形框内亮度和；

        //循环打印判断
        qDebug()<<"*****NO.2******"<<sumValue_2;
        static int flag_time_2 = 0;
        static double t1_2=0,t2_2=0;
        static int LanneLightSum_prev_2;			//车道亮度和：上一帧的
        if(sumValue_2 > 30000)
        {
            if(flag_time== 0)
            {
                //开始计时
                t1_2 = (double)cv::getCPUTickCount();
                flag_time_2 = 1;
            }
        }

        if (LanneLightSum_prev_2 > 30000  && sumValue_2 <= 30000)
        {
            if(flag_time_2== 1)
            {
                //结束计时
                t2_2 = (double)cv::getCPUTickCount();
                flag_time_2 = 0;
            }

            //:: 车辆通过了矩形框：上一帧亮度和大于阈值，本帧亮度和小于阈值；车辆计数器自加；
            ++LanneCarCnt_2;
            LanneLightSum_prev_2= sumValue_2;
            // 时间计算
            ui->time1Lb_2->setText(QString("%1ms").arg((int)(1e3 *(t2_2-t1_2)/(double)cv::getTickFrequency())));
        }
        else
            LanneLightSum_prev_2 = sumValue_2;  //存储当前亮度和到LanneLightSum_prev


        qDebug()<<"NO.2:"<<LanneCarCnt_2;
        ui->pass1Lb_2->setText(QString::number(LanneCarCnt_2));
        //速度计算
        int speed_2 = (int)(3.0/((1e3 *(t2-t1)/(double)cv::getTickFrequency())*(1e-3)))*3.6;
        if(speed_2 > 0)
            ui->label_7->setText(QString("%1km/h").arg(speed_2));


        //*****************************************  3  ***********************************
        // 3
        cv::Mat subMat_3 = outImage(rect_3);	//再MOG2的前景提取结果中，取车道标记矩形框区域为subMat矩阵
        cv::Mat sumMat_3;		//积分图 == subMat的积分矩阵
        cv::integral(subMat_3, sumMat_3, CV_32S);		//设置积分矩阵的数据类型为int；
        int sumValue_3 = (int)sumMat_3.at<int>((int)sumMat_3.rows - 1, (int)sumMat_3.cols - 1);  //获取积分图右下角的值，就是矩形框内亮度和；


        //循环打印判断
        qDebug()<<"*****NO.3******"<<sumValue_3;
        static int flag_time_3 = 0;
        static double t1_3=0,t2_3=0;
        static int LanneLightSum_prev_3;			//车道亮度和：上一帧的
        if(sumValue_3 > 30000)
        {
            if(flag_time== 0)
            {
                //开始计时
                t1_3 = (double)cv::getCPUTickCount();
                flag_time_3 = 1;
            }
        }

        if (LanneLightSum_prev_3 > 30000  && sumValue_3 <= 30000)
        {
            if(flag_time_3== 1)
            {
                //结束计时
                t2_3 = (double)cv::getCPUTickCount();
                flag_time_3 = 0;
            }

            //:: 车辆通过了矩形框：上一帧亮度和大于阈值，本帧亮度和小于阈值；车辆计数器自加；
            ++LanneCarCnt_3;
            LanneLightSum_prev_3= sumValue_3;
            // 时间计算
            ui->time1Lb_3->setText(QString("%1ms").arg((int)(1e3 *(t2_3-t1_3)/(double)cv::getTickFrequency())));
        }
        else
            LanneLightSum_prev_3 = sumValue_3;  //存储当前亮度和到LanneLightSum_prev


        qDebug()<<"NO.3:"<<LanneCarCnt_3;
        ui->pass1Lb_3->setText(QString::number(LanneCarCnt_3));
        //速度计算
        int speed_3 = (int)(3.0/((1e3 *(t2_3-t1_3)/(double)cv::getTickFrequency())*(1e-3)))*3.6;
        if(speed_3 > 0)
            ui->label_10->setText(QString("%1km/h").arg(speed_3));


        ui->label_3->setText(QString::number(LanneCarCnt+LanneCarCnt_2+LanneCarCnt_3));//车辆总数
    }

}
